home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / T U R B O Language / Turbo C Tools v6.0 / EXAMPLES / MENU.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  20.5 KB  |  728 lines

  1. /**
  2. *    MENU.C        Display several types of keyboard-activated
  3. *            menus.
  4. *
  5. *  This program displays a series of menus on the screen, allowing
  6. *  the user to choose which of several types of menus will be
  7. *  displayed.
  8. *
  9. *  Five menus are used.  The main menu allows the user to select
  10. *  one of four other menus or to terminate the program.  The
  11. *  main menu is an example of a vertical menu style; the other
  12. *  four exhibit horizontal, grid, Lotus-style, and virtual menus,
  13. *  respectively.
  14. *
  15. *  The command line format is as follows:
  16. *
  17. *    menu [/c | /d | /a]
  18. *
  19. *  The user may specify either /c, /d, or /a, corresponding to the
  20. *  type of mouse style they wish to use; click, drag, or alternate
  21. *  drag, respectively.    If no switch is specified, the default is
  22. *  click.
  23. *
  24. *  The two purposes of MENU are to show off the menuing
  25. *  capabilities of Turbo C TOOLS, and to provide a working example
  26. *  of the proper method of construction and use of the menu
  27. *  functions.
  28. *
  29. *  Version    6.00 (C)Copyright Blaise Computing Inc. 1987-1989
  30. *
  31. **/
  32.  
  33. #include <ctype.h>
  34. #include <stdio.h>
  35.  
  36. #include <bkeybrd.h>
  37. #include <bkeys.h>
  38. #include <bmenu.h>
  39. #include <butil.h>
  40. #include <bmouse.h>
  41.  
  42.         /* Text color is intense white on blue.         */
  43. #define MYTEXTATR (utnybbyt (SC_BLUE,  NORMAL    | INTENSITY))
  44.  
  45.         /* "Lotus" description color is intense magenta on  */
  46.         /* blue.                        */
  47. #define MYLNGATTR (utnybbyt (SC_BLUE,  SC_MAGENTA | INTENSITY))
  48.  
  49.         /* Color of highlight bar is black text on a white  */
  50.         /* background.                        */
  51. #define MYHILATR  (utnybbyt (NORMAL, SC_BLACK))
  52.  
  53.         /* Color of "protected" items is green on blue.     */
  54. #define MYPROATR  (utnybbyt (SC_BLUE,  SC_GREEN))
  55.  
  56.         /* Color of menu borders is cyan on black.        */
  57. #define MYBORDATR (utnybbyt (SC_BLACK, SC_CYAN))
  58.  
  59.         /* Color of menu titles is the same as menu borders.*/
  60. #define MYTITATR  MYBORDATR
  61.  
  62. #define NUL    '\0'
  63. #define TRUE   1
  64. #define FALSE  0
  65.  
  66.         /* Terminate-on-error macro.                */
  67. #define exitBad()                             \
  68.     {                                     \
  69.     mohide(MO_HIDE);                         \
  70.     fprintf (stderr,                         \
  71.          "menu: died with b_wnerr = %d in line %d",          \
  72.          b_wnerr, __LINE__);                     \
  73.     exit (b_wnerr);                          \
  74.     }
  75.  
  76.  
  77.         /* Declare function prototypes.             */
  78. void main    (int, char **);
  79. void horizontal (int, int, int, int, int *, int *);
  80. void lotus    (int, int, int, int, int *, int *);
  81. void grid    (int, int, int, int, int *, int *);
  82. void virtual    (int, int, int, int, int *, int *);
  83.  
  84.  
  85. void main (argc, argv)
  86. int    argc;
  87. char **argv;
  88. {
  89.     BMENU  *pmenu;
  90.     BORDER  border;
  91.     WHERE   where;
  92.     int     ch, scan;
  93.     int     row, col;
  94.     int     rrow, rcol;
  95.     int     showrow, showcol;
  96.     int     adapter, mode, cols, apage;
  97.     int     coff, crow, ccol, chigh, clow;
  98.     int     done = FALSE;
  99.     int     mouse_style = MN_MOU_CLICK;
  100.     int     bad_command_line = 0;
  101.  
  102.         /* First, check to see if the user specified a        */
  103.         /* mouse style.                     */
  104.     if (argc == 2)
  105.     {
  106.         /* Make sure the switch character is valid.        */
  107.     if ((argv[1][0] == '/') || (argv[1][0] == '-'))
  108.     {
  109.         /* Make sure the option character is valid.        */
  110.         switch(toupper(argv[1][1]))
  111.         {
  112.         case 'C':
  113.         mouse_style = MN_MOU_CLICK;
  114.         break;
  115.         case 'D':
  116.         mouse_style = MN_MOU_DRAG;
  117.         break;
  118.         case 'A':
  119.         mouse_style = MN_MOU_ALT_DRAG;
  120.         break;
  121.         default:
  122.         bad_command_line = 1;
  123.         break;
  124.         }
  125.     }
  126.     else
  127.         bad_command_line = 1;
  128.     }
  129.     else
  130.     if (argc > 2)
  131.         bad_command_line = 1;
  132.  
  133.     if (bad_command_line)
  134.     {
  135.     fprintf(stderr, "Usage: menu [/c | /d | /a].\n");
  136.     exit(1);
  137.     }
  138.  
  139.  
  140.         /* Now we make certain that we are in 80 column     */
  141.         /* text video mode.                    */
  142.     adapter = scmode (&mode, &cols, &apage);
  143.     switch (mode)
  144.     {
  145.     case 2:
  146.     case 3:
  147.     case 7:
  148.         break;
  149.  
  150.     default:
  151.         fprintf (stderr,
  152.              "menu: This demonstration works only in 80 column\n");
  153.         fprintf (stderr,
  154.              "      text modes (modes 2, 3, and 7)\n");
  155.         exit (1);
  156.     }
  157.  
  158.         /* Save cursor position and style to restore later. */
  159.     coff = sccurst (&crow, &ccol, &chigh, &clow);
  160.  
  161.         /* Create the menu data structure.            */
  162.     if ((pmenu = mncreate (8, 14,
  163.                MYTEXTATR, MYHILATR,
  164.                MYPROATR, MYLNGATTR)) == NIL)
  165.     exitBad ()
  166.  
  167.         /* Set up items on the menu, and define         */
  168.         /* corresponding keys (upper and lower case of the  */
  169.         /* first letters of the items).             */
  170.     if (mnitmkey (pmenu, 0, 1, 0, "Horizontal", "Hh", MN_NOMOVE) == NIL)
  171.     exitBad ()
  172.     if (mnitmkey (pmenu, 1, 1, 0, "Lotus-Style", "Ll", MN_NOMOVE) == NIL)
  173.     exitBad ()
  174.     if (mnitmkey (pmenu, 2, 1, 0, "Grid", "Gg", MN_NOMOVE) == NIL)
  175.     exitBad ()
  176.     if (mnitmkey (pmenu, 3, 1, 0, "Virtual", "Vv", MN_NOMOVE) == NIL)
  177.     exitBad ()
  178.     if (mnitmkey (pmenu, 5, 1, 0, "Quit", "QqXx", MN_NOMOVE | MN_BEEP)
  179.     == NIL)
  180.     exitBad ()
  181.  
  182.         /* Define the following keys as selection &        */
  183.         /* transmission keys: ALT-H, ALT-L, ALT-G, ALT-V,   */
  184.         /* ALT-Q and X.                     */
  185.     if (mnkey (pmenu,  0,  1, KB_C_A_H, KB_S_A_H,
  186.            MN_SELECT | MN_TRANSMIT, MN_ADD) == NIL)
  187.     exitBad ()
  188.     if (mnkey (pmenu,  1,  1, KB_C_A_L, KB_S_A_L,
  189.            MN_SELECT | MN_TRANSMIT, MN_ADD) == NIL)
  190.     exitBad ()
  191.     if (mnkey (pmenu,  2,  1, KB_C_A_G, KB_S_A_G,
  192.            MN_SELECT | MN_TRANSMIT, MN_ADD) == NIL)
  193.     exitBad ()
  194.     if (mnkey (pmenu,  3,  1, KB_C_A_V, KB_S_A_V,
  195.            MN_SELECT | MN_TRANSMIT, MN_ADD) == NIL)
  196.     exitBad ()
  197.     if (mnkey (pmenu,  5,  1, KB_C_A_Q, KB_S_A_Q,
  198.            MN_SELECT | MN_TRANSMIT | MN_BEEP, MN_ADD) == NIL)
  199.     exitBad ()
  200.     if (mnkey (pmenu,  5,  1, KB_C_A_X, KB_S_A_X,
  201.            MN_SELECT | MN_TRANSMIT | MN_BEEP, MN_ADD) == NIL)
  202.     exitBad ()
  203.  
  204.         /* Disable ESC key.                    */
  205.     if (mnkey (pmenu, 0, 0, KB_C_N_ESC, KB_S_N_ESC,
  206.            MN_ABORT, MN_DELETE) == NIL)
  207.     exitBad ()
  208.  
  209.         /* Now that we have put all of the menu items on    */
  210.         /* the menu in item color, set the native window    */
  211.         /* color so that additional text will appear in the */
  212.         /* menu's window in "long-item" (description) color.*/
  213.     wnsetopt (pmenu->pwin, WN_ATTR, MYLNGATTR);
  214.  
  215.         /* Figure out where to display the menu.        */
  216.     where.dev         = (adapter == 0) ? SC_MONO : SC_COLOR;
  217.     where.page         = 0;
  218.     where.corner.row = 1;
  219.     where.corner.col = 1;
  220.  
  221.         /* Make a border with a top centered title.        */
  222.     border.type     = BBRD_SSSS | BBRD_TCT;
  223.     border.attr     = MYBORDATR;
  224.     border.ch        = NUL;
  225.     border.pttitle  = "Menu Styles";
  226.     border.ttattr   = MYTITATR;
  227.  
  228.         /* Display the menu on the screen.            */
  229.     if (mndsplay (pmenu, &where, &border) == NIL)
  230.     exitBad ()
  231.  
  232.         /* Set up starting row and column for highlight bar.*/
  233.     row = 0;
  234.     col = 1;
  235.  
  236.         /* If the mouse is present, enable its cursor.        */
  237.     if (MO_OK == mohide(MO_SHOW))
  238.     if (NULL == mnmstyle(pmenu, mouse_style, MO_LEFT))
  239.         exitBad ()
  240.  
  241.         /* Leave this menu on the screen until they select  */
  242.         /* the "Quit" entry.                                */
  243.     do
  244.     {
  245.         /* Read a response from the menu.            */
  246.     if (mnread (pmenu, row, col, &row, &col, &ch, &scan,
  247.             MN_KEEP_HIGHLIGHT))
  248.         exitBad ()
  249.  
  250.         /* Set up location to show sub-menu.            */
  251.     showrow = where.corner.row + row + 2;
  252.     showcol = where.corner.col + col + 0;
  253.  
  254.         /* Go do what was requested.                */
  255.     switch (row)
  256.     {
  257.         case 0:
  258.         horizontal (where.dev, showrow, showcol, mouse_style,
  259.                 &rrow, &rcol);
  260.         break;
  261.         case 1:
  262.         lotus (where.dev, showrow, showcol, mouse_style,
  263.                &rrow, &rcol);
  264.         break;
  265.         case 2:
  266.         grid (where.dev, showrow, showcol, mouse_style,
  267.               &rrow, &rcol);
  268.         break;
  269.         case 3:
  270.         virtual (where.dev, showrow, showcol, mouse_style,
  271.              &rrow, &rcol);
  272.         break;
  273.         case 5:
  274.         done = TRUE;
  275.     }
  276.  
  277.         /* At this point, rrow and rcol contain the row and */
  278.         /* column of the item selected from the submenu.    */
  279.     if (!done)
  280.     {    /* Tell the user what was selected from the submenu.*/
  281.         if (b_pcurwin != pmenu->pwin)
  282.         wnselect (pmenu->pwin);
  283.         wnscrblk (b_pcurwin, 6, 0, 6, 13, -1, -1, 0, 0, 0);
  284.         wncurmov (6, 1);
  285.         wnprintf ("xmit (%d %d)", rrow, rcol);
  286.     }
  287.     } while (!done);
  288.  
  289.     mndstroy (pmenu);
  290.  
  291.     mohide(MO_HIDE);
  292.  
  293.         /* Restore cursor position and style.            */
  294.     sccurset (crow, ccol);
  295.     scpgcur (coff, chigh, clow, CUR_NO_ADJUST);
  296. }
  297.  
  298.  
  299.  
  300. /**
  301. *
  302. * Name        HORIZONTAL -- Display and allow user selection from
  303. *                  a simple horizontal menu.
  304. *
  305. * Synopsis    horizontal (dev, row, col, prrow, prcol);
  306. *
  307. *        int dev       Device on which to display the
  308. *                  menu.  Either SC_COLOR or SC_MONO.
  309. *        int row, col      Row and column where the upper-
  310. *                  left corner of the menu's data
  311. *                  area should appear.
  312. *        int mouse_style   The mouse style to use.
  313. *        int *prrow,      Pointers to variables in which to
  314. *            *prcol      return the row and column selected
  315. *                  from the menu.
  316. *
  317. * Description    This function constructs a simple horizontal menu,
  318. *        and waits for user input.  It then returns the row
  319. *        and column of the selection to its caller.
  320. *
  321. * Returns    *prrow, *prcol      Row and column (relative to menu) of
  322. *                  user selection.
  323. *
  324. **/
  325.  
  326.  
  327. void horizontal (dev, row, col, mouse_style, prrow, prcol)
  328. int  dev;
  329. int  row,    col;
  330. int  mouse_style;
  331. int *prrow, *prcol;
  332. {
  333.     BMENU  *pmenu;
  334.     BORDER  border;
  335.     WHERE   where;
  336.     int     ch, scan;
  337.  
  338.         /* Figure out where to display the menu.        */
  339.     where.dev         = dev;
  340.     where.page         = 0;
  341.     where.corner.row = row;
  342.     where.corner.col = col;
  343.  
  344.         /* Create the menu data structure.            */
  345.     if ((pmenu = mncreate (1, 28,
  346.                MYTEXTATR, MYHILATR,
  347.                MYPROATR, MYLNGATTR)) == NIL)
  348.     exitBad ()
  349.  
  350.         /* Set up items on the menu, and add keys to the key*/
  351.         /* binding list (upper and lower case of the first  */
  352.         /* letters of the items.                */
  353.     if (mnitmkey (pmenu, 0, 1,    0, "My dog", "MmDd",   MN_NOMOVE) == NIL)
  354.     exitBad ()
  355.     if (mnitmkey (pmenu, 0, 9,    0, "has", "Hh",   MN_NOMOVE) == NIL)
  356.     exitBad ()
  357.     if (mnitmkey (pmenu, 0, 14, 0, "itchy", "Ii",   MN_NOMOVE) == NIL)
  358.     exitBad ()
  359.     if (mnitmkey (pmenu, 0, 21, 0, "fleas.", "Ff",   MN_NOMOVE) == NIL)
  360.     exitBad ()
  361.  
  362.         /* Disable ESC key.                    */
  363.     if (mnkey (pmenu, 0, 0, KB_C_N_ESC, KB_S_N_ESC,
  364.            MN_ABORT, MN_DELETE) == NIL)
  365.     exitBad ()
  366.  
  367.         /* Make a border with a bottom centered title.        */
  368.     border.type     = BBRD_SSSS | BBRD_BCT;
  369.     border.attr     = MYBORDATR;
  370.     border.ch        = NUL;
  371.     border.pbtitle  = "Horizontal Menu";
  372.     border.btattr   = MYTITATR;
  373.  
  374.         /* Display the menu on the screen.            */
  375.     if (mndsplay (pmenu, &where, &border) == NIL)
  376.     exitBad ()
  377.  
  378.         /* Make menu aware of the mouse.            */
  379.     if (NULL == mnmstyle(pmenu, mouse_style, MO_LEFT))
  380.     exitBad ()
  381.  
  382.         /* Read a response from the menu.            */
  383.     if (mnread (pmenu, 0, 1, prrow, prcol, &ch, &scan, MN_DESTROY))
  384.     exitBad ()
  385. }
  386.  
  387.  
  388.  
  389.  
  390. /**
  391. *
  392. * Name        LOTUS -- Display and allow user selection from a
  393. *             "Lotus"-style menu.
  394. *
  395. * Synopsis    lotus (dev, row, col, prrow, prcol);
  396. *
  397. *        int dev       Device on which to display the
  398. *                  menu.  Either SC_COLOR or SC_MONO.
  399. *        int row, col      Row and column where the upper-
  400. *                  left corner of the menu's data
  401. *                  area should appear.
  402. *        int mouse_style   The mouse style to use.
  403. *        int *prrow,      Pointers to variables in which to
  404. *            *prcol      return the row and column selected
  405. *                  from the menu.
  406. *
  407. * Description    This function constructs a "Lotus" menu, and
  408. *        waits for user input.  It then returns the row
  409. *        and column of the selection to its caller.
  410. *
  411. * Returns    *prrow, *prcol      Row and column (relative to menu) of
  412. *                  user selection.
  413. *
  414. **/
  415.  
  416.  
  417. void lotus (dev, row, col, mouse_style, prrow, prcol)
  418. int  dev;
  419. int  row,    col;
  420. int  mouse_style;
  421. int *prrow, *prcol;
  422. {
  423.     BMENU  *pmenu;
  424.     BORDER  border;
  425.     WHERE   where;
  426.     int     ch, scan;
  427.  
  428.         /* Figure out where to display the menu.        */
  429.     where.dev         = dev;
  430.     where.page         = 0;
  431.     where.corner.row = row;
  432.     where.corner.col = col;
  433.  
  434.         /* Create the menu data structure.            */
  435.     if ((pmenu = mncreate (2, 70,
  436.                MYTEXTATR, MYHILATR,
  437.                MYPROATR, MYLNGATTR)) == NIL)
  438.     exitBad ()
  439.  
  440.         /* Set up items on the menu, and add keys to the key*/
  441.         /* binding list (upper and lower case of the first  */
  442.         /* letters of the items.                */
  443.     if (mnlitkey (pmenu, 0, 0, 0, "Worksheet", 1, 0,
  444.     "Global, Insert, Delete, Column-Width, Erase, Titles, Window, Status",
  445.     "Ww",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  446.     exitBad ()
  447.  
  448.     if (mnlitkey (pmenu, 0, 11, 0, "Range", 1, 0,
  449.     "Format, Label-Prefix, Erase, Name, Justify, Protect, Unprotect, Input",
  450.     "Rr",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  451.     exitBad ()
  452.  
  453.     if (mnlitkey (pmenu, 0, 18, 0, "Copy", 1, 0,
  454.     "Copy a cell or range of cells",
  455.     "Cc",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  456.     exitBad ()
  457.  
  458.     if (mnlitkey (pmenu, 0, 24, 0, "Move", 1, 0,
  459.     "Move a cell or range of cells",
  460.     "Mm",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  461.     exitBad ()
  462.  
  463.     if (mnlitkey (pmenu, 0, 30, 0, "File", 1, 0,
  464.     "Retrieve, Save, Combine, Xtract, Erase, List, Import, Directory",
  465.     "Ff",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  466.     exitBad ()
  467.  
  468.     if (mnlitkey (pmenu, 0, 36, 0, "Print", 1, 0,
  469.     "Output a range to the printer or a print file",
  470.     "Pp",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  471.     exitBad ()
  472.  
  473.     if (mnlitkey (pmenu, 0, 43, 0, "Graph", 1, 0,
  474.     "Create a graph",
  475.     "Gg",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  476.     exitBad ()
  477.  
  478.     if (mnlitkey (pmenu, 0, 50, 0, "Data", 1, 0,
  479.     "Fill, Table, Sort, Query, Distribution",
  480.     "Dd",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  481.     exitBad ()
  482.  
  483.     if (mnlitkey (pmenu, 0, 56, 0, "Quit", 1, 0,
  484.     "End 3-2-1 Session (Have you saved your play ?)",
  485.     "Qq",   MN_NOMOVE | MN_TRANSMIT) == NIL)
  486.     exitBad ()
  487.  
  488.         /* Disable ESC key.                    */
  489.     if (mnkey (pmenu, 0, 0, KB_C_N_ESC, KB_S_N_ESC,
  490.            MN_ABORT, MN_DELETE) == NIL)
  491.     exitBad ()
  492.  
  493.         /* Make a border with a top centered title.        */
  494.     border.type     = BBRD_SDDD | BBRD_TCT;
  495.     border.attr     = MYBORDATR;
  496.     border.ch        = NUL;
  497.     border.pttitle  = "Lotus Menu  (with top-centered title)";
  498.     border.ttattr   = MYTITATR;
  499.  
  500.         /* Display the menu on the screen.            */
  501.     if (mndsplay (pmenu, &where, &border) == NIL)
  502.     exitBad ()
  503.  
  504.         /* Make menu aware of the mouse.            */
  505.     if (NULL == mnmstyle(pmenu, mouse_style, MO_LEFT))
  506.     exitBad ()
  507.  
  508.         /* Read a response from the menu.            */
  509.     if (mnlread (pmenu, 0, 0, prrow, prcol, &ch, &scan, MN_DESTROY))
  510.     exitBad ()
  511. }
  512.  
  513.  
  514.  
  515.  
  516. /**
  517. *
  518. * Name        GRID -- Display and allow user selection from a
  519. *            grid menu.
  520. *
  521. * Synopsis    grid (dev, row, col, prrow, prcol);
  522. *
  523. *        int dev       Device on which to display the
  524. *                  menu.  Either SC_COLOR or SC_MONO.
  525. *        int row, col      Row and column where the upper-
  526. *                  left corner of the menu's data
  527. *                  area should appear.
  528. *        int mouse_style   The mouse style to use.
  529. *        int *prrow,      Pointers to variables in which to
  530. *            *prcol      return the row and column selected
  531. *                  from the menu.
  532. *
  533. * Description    This function constructs a grid menu, and
  534. *        waits for user input.  It then returns the
  535. *        row and column of the selection to its caller.
  536. *
  537. * Returns    *prrow, *prcol      Row and column (relative to menu) of
  538. *                  user selection.
  539. *
  540. **/
  541.  
  542.  
  543. void grid (dev, row, col, mouse_style, prrow, prcol)
  544. int  dev;
  545. int  row,    col;
  546. int  mouse_style;
  547. int *prrow, *prcol;
  548. {
  549.     BMENU  *pmenu;
  550.     BORDER  border;
  551.     WHERE   where;
  552.     int     ch, scan, x, y;
  553.     char    s[3];
  554.  
  555.         /* Figure out where to display the menu.        */
  556.     where.dev         = dev;
  557.     where.page         = 0;
  558.     where.corner.row = row;
  559.     where.corner.col = col;
  560.  
  561.         /* Create the menu data structure.            */
  562.     if ((pmenu = mncreate (6, 40,
  563.                MYTEXTATR, MYHILATR,
  564.                MYPROATR, MYLNGATTR)) == NIL)
  565.     exitBad ()
  566.  
  567.         /* Set up items on the menu.  We will make a grid   */
  568.         /* of numbers from 0 to 47, in rows across the        */
  569.         /* menu.                        */
  570.     for (y = 0;  y < 6;  y++)
  571.     for (x = 0;  x < 8;  x++)
  572.         /* Put a the ASCII characters for a number (y*8+x)  */
  573.         /* at location (y, x*5) in the menu.            */
  574.         if (mnitem (pmenu, y, (x * 5), 0,
  575.             itoa (((y * 8) + x), s, 10)) == NIL)
  576.          exitBad ()
  577.  
  578.         /* Disable ESC key.                    */
  579.     if (mnkey (pmenu, 0, 0, KB_C_N_ESC, KB_S_N_ESC,
  580.            MN_ABORT, MN_DELETE) == NIL)
  581.     exitBad ()
  582.  
  583.         /* Make a border with a bottom left title.        */
  584.     border.type     = BBRD_SSSS | BBRD_BLT;
  585.     border.attr     = MYBORDATR;
  586.     border.ch        = NUL;
  587.     border.pbtitle  = "Grid Menu  (bottom left title)";
  588.     border.btattr   = MYTITATR;
  589.  
  590.         /* Display the menu on the screen.            */
  591.     if (mndsplay (pmenu, &where, &border) == NIL)
  592.     exitBad ()
  593.  
  594.         /* Make menu aware of the mouse.            */
  595.     if (NULL == mnmstyle(pmenu, mouse_style, MO_LEFT))
  596.     exitBad ()
  597.  
  598.         /* Read a response from the menu.            */
  599.     if (mnread (pmenu, 0, 0, prrow, prcol, &ch, &scan, MN_DESTROY))
  600.     exitBad ()
  601. }
  602.  
  603.  
  604. /**
  605. *
  606. * Name        VIRTUAL -- Display and allow user selection from
  607. *               a virtual menu.
  608. *
  609. * Synopsis    virtual (dev, row, col, prrow, prcol);
  610. *
  611. *        int dev       Device on which to display the
  612. *                  menu.  Either SC_COLOR or SC_MONO.
  613. *        int row, col      Row and column where the upper-
  614. *                  left corner of the menu's data
  615. *                  area should appear.
  616. *        int mouse_style   The mouse style to use.
  617. *        int *prrow,      Pointers to variables in which to
  618. *            *prcol      return the row and column selected
  619. *                  from the menu.
  620. *
  621. * Description    This function constructs a virtual menu, and waits
  622. *        for user input.  It then returns the row and column of
  623. *        the selection to its caller.
  624. *
  625. * Returns    *prrow, *prcol      Row and column (relative to menu) of
  626. *                  user selection.
  627. *
  628. **/
  629.  
  630.  
  631. void virtual (dev, row, col, mouse_style, prrow, prcol)
  632. int  dev;
  633. int  row,    col;
  634. int  mouse_style;
  635. int *prrow, *prcol;
  636. {
  637.     BMENU  *pmenu;
  638.     BORDER  border;
  639.     WHERE   where;
  640.     int     ch, scan;
  641.  
  642.         /* Figure out where to display the menu.        */
  643.     where.dev         = dev;
  644.     where.page         = 0;
  645.     where.corner.row = row;
  646.     where.corner.col = col;
  647.  
  648.         /* Create the menu data structure.            */
  649.     if ((pmenu = mncreate (7, 39,
  650.                MYTEXTATR, MYHILATR,
  651.                MYPROATR, MYLNGATTR)) == NIL)
  652.     exitBad ()
  653.  
  654.         /* Set up items on the menu, and add keys to the key*/
  655.         /* binding list (upper and lower case of the first  */
  656.         /* letters of the items).                */
  657.  
  658.         /* First, items on the menu at a Chinese restaraunt.*/
  659.     if (mnitmkey (pmenu, 0, 0, 0, "Mandarin Chicken", "Mm",
  660.           MN_NOMOVE) == NIL)
  661.     exitBad ()
  662.     if (mnitmkey (pmenu, 1, 0, 0, "Broccoli Beef", "Bb",
  663.           MN_NOMOVE) == NIL)
  664.     exitBad ()
  665.     if (mnitmkey (pmenu, 2, 0, 0, "Sweet & Sour Pork", "Ss",
  666.           MN_NOMOVE) == NIL)
  667.     exitBad ()
  668.     if (mnitmkey (pmenu, 3, 0, 0, "Won Ton Soup", "Ww",
  669.           MN_NOMOVE) == NIL)
  670.     exitBad ()
  671.     if (mnitmkey (pmenu, 4, 0, 0, "Pork Fried Rice", "Pp",
  672.           MN_NOMOVE) == NIL)
  673.     exitBad ()
  674.     if (mnitmkey (pmenu, 5, 0, 0, "Potstickers", "Pp",
  675.           MN_NOMOVE) == NIL)
  676.     exitBad ()
  677.     if (mnitmkey (pmenu, 6, 0, 0, "Fortune Cookies", "Ff",
  678.           MN_NOMOVE) == NIL)
  679.     exitBad ()
  680.  
  681.         /* Now, items on the menu at an Italian restaraunt. */
  682.     if (mnitmkey (pmenu, 0, 19, 0, "Lasagna", "Ll",
  683.           MN_NOMOVE) == NIL)
  684.     exitBad ()
  685.     if (mnitmkey (pmenu, 1, 19, 0, "Tortellini Pesto", "Tt",
  686.           MN_NOMOVE) == NIL)
  687.     exitBad ()
  688.     if (mnitmkey (pmenu, 2, 19, 0, "Ravioli w/Meat Sauce", "Rr",
  689.           MN_NOMOVE) == NIL)
  690.     exitBad ()
  691.     if (mnitmkey (pmenu, 3, 19, 0, "Fettucini Al Fredo", "Ff",
  692.           MN_NOMOVE) == NIL)
  693.     exitBad ()
  694.     if (mnitmkey (pmenu, 4, 19, 0, "Veal Parmesan", "Vv",
  695.           MN_NOMOVE) == NIL)
  696.     exitBad ()
  697.     if (mnitmkey (pmenu, 5, 19, 0, "Linguini", "Ll",
  698.           MN_NOMOVE) == NIL)
  699.     exitBad ()
  700.     if (mnitmkey (pmenu, 6, 19, 0, "Calamari", "Cc",
  701.           MN_NOMOVE) == NIL)
  702.     exitBad ()
  703.  
  704.         /* Disable ESC key.                    */
  705.     if (mnkey (pmenu, 0, 0, KB_C_N_ESC, KB_S_N_ESC,
  706.            MN_ABORT, MN_DELETE) == NIL)
  707.     exitBad ()
  708.  
  709.         /* Make a border with a bottom centered title.        */
  710.     border.type     = BBRD_SSSS | BBRD_BCT;
  711.     border.attr     = MYBORDATR;
  712.     border.ch        = NUL;
  713.     border.pbtitle  = "Virtual";
  714.     border.btattr   = MYTITATR;
  715.  
  716.         /* Display the menu in a 4 X 30 viewport.        */
  717.     if (mnvdisp (pmenu, &where, 4, 30, 0, 0, &border) == NIL)
  718.     exitBad ()
  719.  
  720.         /* Make menu aware of the mouse.            */
  721.     if (NULL == mnmstyle(pmenu, mouse_style, MO_LEFT))
  722.     exitBad ()
  723.  
  724.         /* Read a response from the menu.            */
  725.     if (mnread (pmenu, 0, 0, prrow, prcol, &ch, &scan, MN_DESTROY))
  726.     exitBad ()
  727. }
  728.